package com.example.kingdee.kingdeeBridge.kingdeeAbs;

import com.alibaba.fastjson2.JSON;
import com.example.kingdee.exception.ProcedureException;
import com.example.kingdee.kingdeeBridge.common.RequestResult;
import com.example.kingdee.kingdeeBridge.dto.BillWriteInDto;
import com.example.kingdee.kingdeeBridge.dto.PushDto;
import com.example.kingdee.kingdeeBridge.entity.SrcBillEntry;
import com.example.kingdee.kingdeeBridge.kingdeeImpl.BillImpl;
import com.example.kingdee.sqlTool.singleton.Singleton;
import com.example.kingdee.sqlTool.sqltoolEnum.FormIdEnum;
import com.google.gson.Gson;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.entity.SuccessEntity;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;


public class FolderKingdee extends KingdeeAbstract{

    private static K3CloudApi k3CloudApi;

    public FolderKingdee(BillImpl billImpl) {
        super(billImpl);
    }



    static {
        try {
            k3CloudApi = Singleton.getInstance();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *
     * @param fid 表id
     * @return
     */
    @Override
    //查询目标单据行id和源单行id
    public Map<String, String> selectTargetBillEntry(String fid){
        return super.selectTargetBillEntry(fid);
    }

    @Override
    /**
     *
     * @param fid 表id
     * @param srcBillEntryList 源单信息
     * @param targetInfo 目标单据行id和源单行id对应关系
     * @return
     */
    public RequestResult updateTargetBillEntry(String fid, BillWriteInDto billWriteInDto, Map<String, String> targetInfo){
        RequestResult requestResult = super.updateTargetBillEntry(fid, billWriteInDto, targetInfo);
        //下推失败则提示错误信息并删除目标单据
        if (requestResult.getCode().equals("500")){
            super.deleteTargetBill(fid);
            throw new ProcedureException(requestResult.getMsg());
        }
        return requestResult;
    }

    //提交审核目标单据
    public void auditTargetBill(String billNo) {
        super.auditTargetBill(billNo);
    }

    //删除目标单据
    public void deleteTargetBill(String fid){
        super.deleteTargetBill(fid);
    }

    //后置操作
    public void postPosition(String billNo){
        super.postPosition(billNo);
    }

    //填充明细行id
    public void addPushDtoEntryIds(PushDto pushDto, List<SrcBillEntry> srcBillEntryList){
        StringBuilder entryIdsBuffer = new StringBuilder();
        for (int i = 0; i < srcBillEntryList.size(); i++) {
            SrcBillEntry srcBillEntry = srcBillEntryList.get(i);
            if (i != srcBillEntryList.size() - 1){
                entryIdsBuffer.append(srcBillEntry.getEntryId()).append(",");
            }else {
                entryIdsBuffer.append(srcBillEntry.getEntryId());
            }
        }
        pushDto.setEntryIds(entryIdsBuffer.toString());
    }

    //单据下推
    public RequestResult pushDown(PushDto pushDto) {
        String resultJson;
        try{
            //业务对象标识
            String formId = FormIdEnum.getDBTableName(pushDto.getSrcFormId().name());
            LinkedHashMap<String, Object> data = new LinkedHashMap<>();
            //单据内码集合，字符串类型，格式："Id1,Id2,..."（使用内码时必录）
            if (pushDto.getIds() != null && pushDto.getIds().size() != 0){
                data.put("ids", pushDto.getIds());
            }
            //单据编码集合，数组类型，格式：[No1,No2,...]（使用编码时必录）
            if (pushDto.getNumbers() != null && pushDto.getNumbers().size() != 0){
                data.put("Numbers", pushDto.getNumbers());
            }
            //分录内码集合，逗号分隔（分录下推时必录） 注（按分录下推时，单据内码和编码不需要填,否则按整单下推）
            if (!StringUtils.isEmpty(pushDto.getEntryIds())){
                data.put("EntryIds", pushDto.getEntryIds());
            }
            //转换规则内码，字符串类型（未启用默认转换规则时，则必录）
            if (!StringUtils.isEmpty(pushDto.getRuleId())){
                data.put("RuleId", pushDto.getRuleId());
            }
            //目标单据类型内码，字符串类型（非必录）
            if (!StringUtils.isEmpty(pushDto.getTargetBillTypeId())){
                data.put("TargetBillTypeId", pushDto.getTargetBillTypeId());
            }
            //目标单据FormId，字符串类型，（启用默认转换规则时，则必录）
            if (pushDto.getTargetOrgId() != null){
                data.put("TargetOrgId", pushDto.getTargetOrgId());
            }
            //目标单据FormId，字符串类型，（启用默认转换规则时，则必录）
            if (pushDto.getTargetFormId() != null){
                data.put("TargetFormId", FormIdEnum.getDBTableName(pushDto.getTargetFormId().name()));
            }
            //是否启用默认转换规则，布尔类型，默认false（非必录）
            data.put("IsEnableDefaultRule", pushDto.isEnableDefaultRule());
            //保存失败时是否暂存，布尔类型，默认false（非必录）  注（暂存的单据是没有编码的）
            data.put("IsDraftWhenSaveFail", true);
            String query = JSON.toJSONString(data);
            //调用接口
            resultJson = k3CloudApi.push(formId,query);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ProcedureException("调用下推接口失败", e);
        }
        //用于记录结果
        Gson gson = new Gson();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson(resultJson, RepoRet.class);
        RequestResult requestResult = new RequestResult();
        if (!repoRet.getResult().getResponseStatus().isIsSuccess()) {
            //获取错误信息
            String errorMessage = repoRet.getResult().getResponseStatus().getErrors().get(0).getMessage();
            requestResult.setCode("500");
            requestResult.setMsg(errorMessage);
        }else {
            SuccessEntity successEntity = repoRet.getResult().getResponseStatus().getSuccessEntitys().get(0);
            requestResult.setCode("200");
            requestResult.setId(successEntity.getId());
            requestResult.setNumber(successEntity.getNumber());
            requestResult.setDIndex(successEntity.getDIndex());
            requestResult.setBillNo(successEntity.getBillNo());
        }
        //下推失败则提示错误信息并删除目标单据
        if (requestResult.getCode().equals("500")){
            super.deleteTargetBill(requestResult.getId());
            throw new ProcedureException(requestResult.getMsg());
        }
        return requestResult;
    }

}
